package sanrenxing.dayEnd.backRepertoryTotal.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import sanrenxing.dayEnd.backRepertoryTotal.dao.EarningAlipayDao;
import sanrenxing.dayEnd.backRepertoryTotal.dao.FundAllocationDao;
import sanrenxing.dayEnd.backRepertoryTotal.domain.*;
import sanrenxing.dayEnd.backRepertoryTotal.service.EarningAlipayService;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
/**
 * @authors name:邓志强
 * @descriptions:收益支付业务层类
 * @date: 2021/5/14 11:31
 * @version:1.0
 */
@Service("earningAlipayService")
@Transactional(propagation = Propagation.REQUIRED)
public class EarningAlipayServiceImpl implements EarningAlipayService {

    //注入收益支付dao对象
    @Autowired
    private EarningAlipayDao earningAlipayDao;

    //注入资金调拨dao对象
    @Autowired
    private FundAllocationDao fundAllocationDao;

    /**
     * 收益支付显示现金利息数据
     * @param start 开始位置
     * @param end 结束位置
     * @return 返回现金利息数据
     */
    @Override
    public List<CashAlipay> queryCash(int start ,int end) {
        //调用查询现金利息方法，传入开始位置和结束位置
        return earningAlipayDao.queryCash(start,end);
    }

    /**
     * 收益支付查询现金利息行数
     * @return 返回现金利息行数
     */
    @Override
    public int queryCashCount() {
        //调用查询现金利息行数方法
        return earningAlipayDao.queryCashCount();
    }

    /**
     * 收益支付显示两费数据
     * @param start 两费数据开始位置
     * @param end 两费数据结束位置
     * @return 返回两费数据
     */
    @Override
    public List<TwoAlipay> queryTwo(int start, int end) {
        //调用查询两费数据的方法，传入开始位置和结束位置
        return earningAlipayDao.queryTwo(start,end);
    }

    /**
     * 收益支付两费行数
     * @return 返回两费行数
     */
    @Override
    public int twoCount() {
        //调用获取两费行数的方法
        return earningAlipayDao.twoCount();
    }

    /**
     * 收益支付显示债券利息数据
     * @param start 开始位置
     * @param end 结束位置
     * @return 返回债券利息数据
     */
    @Override
    public List<BondAlipay> queryBond(int start, int end) {
        //调用返回债券利息数据，传入开始位置和结束位置
        return earningAlipayDao.queryBond(start, end);
    }

    /**
     * 获取债券利息行数
     * @return 返回行数
     */
    @Override
    public int bondCount() {
        //调用获取债券利息行数的方法
        return earningAlipayDao.bondCount();
    }

    /**
     * 收益支付时点击支付
     * @return 返回布尔值
     */
    @Override
    public Boolean total(){
        //创建时间转换对象
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        //首先处理现金支付，也就是处理现金应收应付数据
        //调用支付现金业务方法，传入当天日期，定义变量接收集合；处理存款利息 ：从存款业务中查询出当天到账数据，
        List<AlipayCash> alipayCashes = earningAlipayDao.alipayCash(dateFormat.format(new Date()));
        //遍历到账的数据
        for (AlipayCash alipayCash : alipayCashes) {
            //冲销现金应收应付数据
            //计算应删现金应收应付对应金额的数据 :总金额*卡号利率/计息总天数，定义变量接收
            double rates=(alipayCash.getDepMoney()*alipayCash.getCardRate())/alipayCash.getDayCount();
            //创建大十进制对象，构造传入应收应付金额，调用修改规模方法，传入规模2和完整的一半，最后调用双精度值返回定义变量接收
            double rate = new BigDecimal(rates).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
            //取出计息时间：遍历计息时间，也就相当于删除多少条现金应收应付
            //调用获得天数方法，定义变量接收
            int dayCount = alipayCash.getDayCount();
            //判断天数不等于零
            if (dayCount!=0){
                //则前递增
                ++dayCount;
            }
            //收益支付对象调用添加基金方法，传入应收应付金额、现金编号、天数，返回基金集合定义变量接收;取出总金额添加到资金调拨
            List<FundAllocation> addFA = earningAlipayDao.addFA(rate, alipayCash.getCaId(), dayCount);
            //遍历集合；删掉的应收应付添加到资金调拨
            for (FundAllocation fundAllocation : addFA) {
                //修改类调拨类型为现金利息
                fundAllocation.setReType("现金利息");
                //修改业务日期为当天
                fundAllocation.setBusinDate(new Date());
                //修改调拨日期为当天
                fundAllocation.setReDate(new Date());
                //修改调拨方向为流入
                fundAllocation.setDial(1);
                //修改标记未处理
                fundAllocation.setMark("未处理");
                //调用添加资金调拨的方法
                fundAllocationDao.add(fundAllocation);
            }
            //支付对象调用删除现金应收应付 根据传入:利息 现金编号 类型(存款利息) 删除行数(计息总天数)
            earningAlipayDao.deleteSec(rate,alipayCash.getCaId(),"存款利息",dayCount);
            //创建基金对象；将即将删除的现金存款的数据添加到资金调拨
            FundAllocation fundat = new FundAllocation();
            //修改基金编号为支付现金对象的基金编号
            fundat.setFundId(alipayCash.getFundId());
            //修改现金编号为支付现金对象的现金编号
            fundat.setCaId(Integer.parseInt(alipayCash.getCaId()));
            //修改调拨类型为存款到期
            fundat.setReType("存款到期");
            //修改调拨金额为支付现金对象的存款金额
            fundat.setReMoney(alipayCash.getDepMoney());
            //修改业务日期为当天日期
            fundat.setBusinDate(new Date());
            //修改调拨日期为当天日期
            fundat.setReDate(new Date());
            //修改标记为未处理
            fundat.setMark("未处理");
            //修改流动方向为流入
            fundat.setDial(1);
            //调用添加方法将基金传入
            fundAllocationDao.add(fundat);

        }
        //支付对象调用删除存款(支付)现金到期的数据，传入当天日期
        earningAlipayDao.deleteAlipayCash(dateFormat.format(new Date()));
        //现金库存的现金利息收入
        //支付对象调用方法取得现金库存的现金账号定义集合接收
        List<Integer> cashStockId = earningAlipayDao.cashStockId();
        //遍历现金账户编号
        for (Integer cashId : cashStockId) {
            //通过现金账户从现金应收应付查询存款数据添加到现金应收应付
            //支付对象调用查询现金库存应收应付对象传入现金账户编号，定义集合接收
            List<FundAllocation> fundAllocations = earningAlipayDao.queryCashStockSec(String.valueOf(cashId));
            //遍历基金集合
            for (FundAllocation fundAllocation : fundAllocations) {
                //修改调拨类型为现金利息
                fundAllocation.setReType("现金利息");
                //修改调拨日期为当天
                fundAllocation.setReDate(new Date());
                //修改业务日期为当天
                fundAllocation.setBusinDate(new Date());
                //修改流向为流入
                fundAllocation.setDial(1);
                //修改标记为未处理
                fundAllocation.setMark("未处理");
                //调用方法添加资金调拨
                fundAllocationDao.add(fundAllocation);
            }
            //支付对象调用删除现金库存应收应付中现金库存产生的利息数据，传入现金编号
            earningAlipayDao.deleteCashStockSec(String.valueOf(cashId));
        }


        //债券支付
        //支付对象调用取出所有债券编号，定义集合接收，计算其付息时间是否为今天
        List<BondAlipaySec> alipaySecs = earningAlipayDao.queryBondId();
        //遍历债券
        for (BondAlipaySec alipaySec : alipaySecs) {
            //取出付息次数定义变量接收
            int noipNum = alipaySec.getNoipNum();
            //每次付息相隔时间：天数/付息次数，定义变量接收
            int days=alipaySec.getDayCount()/alipaySec.getNoipNum();
            //定义存储数量(天数)变量赋默认值
            int num=0;
            //遍历次数
            for (int i = 0; i < noipNum; i++) {
                //存储数量递增相隔时间
                num+=days;
                //创建日期对象，获得实例定义变量接收
                Calendar instance = Calendar.getInstance();
                try {
                    //日历对象中存入债券的开始时间(需要格式解析)，输入起始日期
                    instance.setTime(dateFormat.parse(alipaySec.getBeginInte()));
                    //日历对象调用方法减去相应天数
                    instance.add(Calendar.DATE,num);
                    //取得减去(日历时间)天数后的日期，判断是否等于今天，需要进行格式转换
                    if (dateFormat.format(instance.getTime()).equals(dateFormat.format(new Date()))){
                        //今天是债券的付息时间，进行付息
                        //支付对象调用添加债券现金方法传入证券编号并定义基金集合接收；添加资金调拨
                        List<FundAllocation> fundAllocations = earningAlipayDao.addBondCash(alipaySec.getSeId());
                        //遍历集合
                        for (FundAllocation fundAllocation : fundAllocations) {
                            //修改调拨类型为债券利息
                            fundAllocation.setReType("债券利息");
                            //修改标记为未处理
                            fundAllocation.setMark("未处理");
                            //修改流动方向为流入
                            fundAllocation.setDial(1);
                            //调用资金调拨添加方法
                            fundAllocationDao.add(fundAllocation);
                        }
                        //支付对象调用删除债券现金方法，传入证券编号
                        earningAlipayDao.deleteBondCash(alipaySec.getSeId());
                    }
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }
            //查询证券库存中到期的债券----- 因为老师说，债券不能自动卖出
        }

        //两费支付
        //将应支付的两费添加到资金调拨
        //支付对象调用添加两费金额方法定义集合接收
        List<FundAllocation> twoFundAllocations = earningAlipayDao.addTwoMoney();
        //遍历集合
        for (FundAllocation twoFundAllocation : twoFundAllocations) {
            //修改流动方向为流出
            twoFundAllocation.setDial(-1);
            //修改标记为未处理
            twoFundAllocation.setMark("未处理");
            //调用资金调拨添加方法
            fundAllocationDao.add(twoFundAllocation);
        }
        //支付对象调用删除现金应收应付中的两费
        earningAlipayDao.deleteTowMoney();
        //返回正确
        return true;
    }
}
